package com.hardydou.concurrent;

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.RecursiveTask;

/**
 * 分治线程池 示例
 * <p>
 * 示例目的：
 * 1、测试 分合能力
 * 2、测试 work-stealing（工作窃取）能力
 * <p>
 * 示例逻辑：
 * 计算1+2+3+…… 1000
 * 每个线程每0.5秒➕一个数字
 */
public class ForkJoinDemo {

    public static long calAdd(int start, int end) {
        int s = start, e = end, len = 2;
        ForkJoinPool pool = new ForkJoinPool(2);
        long r = pool.invoke(new AddTask(s, e, len));
        return r;
    }

    public static long add(int s, int e) {
        long r = 0;
        for (int i = s; i <= e; i++) {
            r += i;
            try {
                Thread.sleep(200L);
            } catch (Exception ee) {
                ee.printStackTrace();
            }
        }
        System.out.println(Thread.currentThread().getName() + " cal " + s + " , " + e + " over!!");
        return r;
    }

}


class AddTask extends RecursiveTask<Long> {
    /**
     * 开始值
     */
    private final int s;
    /**
     * 结束值
     */
    private final int e;
    /**
     * 任何长度
     */
    private int len;

    public AddTask(int s, int e, int len) {
        this.s = s;
        this.e = e;
        this.len = len;
    }

    @Override
    protected Long compute() {
        if (e - s + 1 <= len) {
            return ForkJoinDemo.add(s, e);
        }
        //拆分任务
        int m = (s + e) / 2;
        AddTask leftTask = new AddTask(s, m, len);
        AddTask rightTask = new AddTask(m + 1, e, len);

        leftTask.fork();
        rightTask.fork();
        long a = leftTask.join();
        long b = rightTask.join();
        return a + b;

    }
}